// 项目设计数据库操作（基于mysql和oracle）
package daos

import (
	"bsm/logger"
	"bsm/models"
	"database/sql"
	"errors"
	"strings"

	"github.com/jmoiron/sqlx"
	_ "github.com/sijms/go-ora/v2"
)

// 定义DAO接口
type DesignDao interface {
	Reset()
	// 开启一个工作单元（事务）
	Begin() error
	// 提交/回滚
	Commit() error
	Rollback() error
	InTransaction(fn func() error) error

	// 事务性操作
	// SaveProjectTable(data models.WebProjectTable) error
	SetProjectBase(project *models.ProjectBase) error
	SetProjectConfig(config models.ProjectDesignConfig) error
	SetProjectLabors(designcode string, designtype int, items []models.LaborItem) error
	SetProjectConversions(labor_id string, items []models.NormConversionItem) error

	SetLaborMachines(items []models.LaborItem) error
	SetLaborInstruments(items []models.LaborItem) error

	SetProjectMachines(labor_id string, items []models.MachineItem) error
	SetProjectInstruments(labor_id string, items []models.InstrumentItem) error
	SetProjectMaterials(pcode string, designtype int, items []models.MaterialItem) error
	SetProjectOtherFee(designcode string, designtype int, items []models.OtherFeeItem) error
	ClearProjectLabors(designcode string, designtype int) error
	ClearProjectMaterials(designcode string, designtype int) error
	ClearProjectOtherFee(designcode string, designtype int) error
	DeleteProjectBase(designcode string) error

	// FileProject(pcode string, designtype int) error // 设置项目存档
	SetProjectState(pcode string, state int) error // 设置项目状态

	// 非事务操作
	// 获取组织列表
	GetOrgList() ([]models.Org, error)

	GetProjectBase(pcode string) (*models.ProjectBase, error)
	GetProjectBaseLite(pcode string) (*models.ProjectBaseLite, error)
	GetProjectConfig(pcode string) (*models.ProjectDesignConfig, error)
	GetDesignNormByCode(normcode string) ([]models.DesignNorm, error)
	GetNormConversion(normcode string) ([]models.WebProjectNormConversionItem, error)
	GetDesignMaterialByCode(mtlcode string) ([]models.DesignMaterial, error)
	GetMaxProjectCode(id *string, prefix, pos string) error
	GetLaborCost(pcode string, designtype int) ([]models.ProjectLaborLite, error) //获取项目的技工数量和普工数量
	GetMachineCost(pcode string, designtype int) ([]models.ProjectMachineLite, error)
	GetInstrumentCost(pcode string, designtype int) ([]models.ProjectInstrumentLite, error)
	GetMaterialCost(pcode string, designtype int) (float64, int, error)
	GetDesignCodeList(orgcode string, designtype int) ([]string, error)
	GetDesignID(code string) (int, error)
	GetLaborList(pcode string, designtype int) ([]models.WebProjectLaborItem, error)
	GetConversionList(labor_lid string) ([]models.WebProjectNormConversionItem, error)
	GetMachineList(labor_lid string) ([]models.WebProjectMachineItem, error)
	GetInstrumentList(Labor_lid string) ([]models.WebProjectInstrumentItem, error)
	GetMaterialList(pcode string, designtype int) ([]models.WebProjectMaterialItem, error)
	GetOtherFee(pcode string, designtype int) ([]models.OtherFeeItem, error)

	UpdateDesignTime(designcode string, designtype int) error

	GetProjects(orgcode string, designtype int) ([]models.ProjectLite, error)
	GetProjectState(pcode string) (int, error)
}

// 实现接口
type designDaoImpl struct {
	dbBsm    *sqlx.DB
	txDesign *sqlx.Tx
}

var CurrentOrgCode string = ""

func NewDesignDao(dbBSM *sqlx.DB) DesignDao {
	return &designDaoImpl{
		dbBsm:    dbBSM,
		txDesign: nil,
	}
}

func (dao *designDaoImpl) Reset() {
	if dao.txDesign != nil {
		dao.Rollback() // 尝试回滚未完成的事务
	}
	dao.txDesign = nil // 确保状态清理
}

// 获取组织列表
func (dao *designDaoImpl) GetOrgList() ([]models.Org, error) {
	var orgList []models.Org
	var err error

	const (
		query = "SELECT id,org_code,org_name,org_level,prefix,fullname,litename,org_inuse FROM bsm_org WHERE org_inuse = 1"
	)

	err = dao.dbBsm.Select(&orgList, query)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetOrgList",
		}).Errorf("获取组织列表失败 - error: %v", err)
		return nil, err
	}
	return orgList, nil
}

func (dao *designDaoImpl) GetDesignNormByCode(normcode string) ([]models.DesignNorm, error) {
	var norm []models.DesignNorm
	var err error

	const (
		query       = "SELECT * FROM norm_labor WHERE norm_inuse = 1"
		queryByCode = query + " AND norm_code like ? "
	)

	if normcode != "" {
		searchTerm := "%" + normcode + "%"
		err = dao.dbBsm.Select(&norm, queryByCode, searchTerm)
	} else {
		err = dao.dbBsm.Select(&norm, query)
	}

	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetDesignNormByCode",
			"norm_code": normcode,
		}).Errorf("获取设计规范失败 - normcode: %s, error: %v", normcode, err)
		return nil, err
	}
	return norm, nil
}

func (dao *designDaoImpl) GetNormConversion(normcode string) ([]models.WebProjectNormConversionItem, error) {
	const (
		query       = "SELECT * FROM norm_labor_conversion "
		queryByCode = query + " WHERE norm_code like ?"
	)

	var items []models.WebProjectNormConversionItem
	var err error
	if normcode != "" {
		searchTerm := "%" + normcode + "%"
		err = dao.dbBsm.Select(&items, queryByCode, searchTerm)
	} else {
		err = dao.dbBsm.Select(&items, query)
	}

	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetNormConversion",
			"norm_code": normcode,
		}).Errorf("获取设计规范转换失败 - normcode: %s, error: %v", normcode, err)
		return nil, err
	}
	return items, nil
}

func (dao *designDaoImpl) GetDesignMaterialByCode(mtlcode string) ([]models.DesignMaterial, error) {
	const (
		query       = "SELECT * FROM norm_material "
		queryByCode = query + " WHERE mat_code like ?"
	)

	var mtl []models.DesignMaterial
	var err error
	if mtlcode != "" {
		searchTerm := "%" + mtlcode + "%"
		err = dao.dbBsm.Select(&mtl, queryByCode, searchTerm)
	} else {
		err = dao.dbBsm.Select(&mtl, query)
	}
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetDesignMaterialByCode",
			"mtl_code":  mtlcode,
		}).Errorf("获取设计材料失败 - mtlcode: %s, error: %v", mtlcode, err)
		return nil, err
	}
	return mtl, nil
}

func (dao *designDaoImpl) GetMaxProjectCode(id *string, prefix, pos string) error {
	const query = `
        SELECT MAX(
            SUBSTRING(design_code, ?)
        ) AS tail 
        FROM project_base 
        WHERE design_code LIKE CONCAT(?, '%')`

	var tail sql.NullString // 使用可以处理NULL的类型
	err := dao.dbBsm.Get(&tail, query, pos, prefix)
	if err != nil {
		if err == sql.ErrNoRows {
			*id = ""
			return nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetMaxProjectCode",
			"prefix":    prefix,
			"pos":       pos,
		}).Errorf("获取最大项目编码失败 - prefix: %s, pos: %s, error: %v", prefix, pos, err)
		return err
	}

	*id = tail.String
	return nil
}

// GetLaborCost 获取项目的技工数量和普工数量
func (dao *designDaoImpl) GetLaborCost(pcode string, designtype int) ([]models.ProjectLaborLite, error) {
	var laborItems []models.ProjectLaborLite

	//获取项目下的人工条目（包含系数）
	query := "select pl.code,pl.lid,pl.quantity,nl.norm_mechanic * nl.norm_ratio as mechanic,nl.norm_general * nl.norm_ratio as general from project_labor pl left join norm_labor nl on pl.code=nl.norm_code where pl.design_code=? and pl.design_type=? "

	args := []interface{}{pcode, designtype}
	err := dao.dbBsm.Select(&laborItems, query, args...)
	if err != nil {
		logger.Errorf("failed to get labor list: %v", err)
		return nil, err
	}
	if len(laborItems) == 0 {
		return nil, nil
	}

	query = "select pl.code,pl.lid,nlc.rate_labor from project_labor_conversion plc left join project_labor pl  on pl.lid=plc.lid left join norm_labor_conversion nlc on plc.nci_id=nlc.id where pl.lid=?"
	type laborConversion struct {
		Code string  `db:"code"`
		Lid  string  `db:"lid"`
		Rate float64 `db:"rate_labor"`
	}

	for i := 0; i < len(laborItems); i++ {
		lid := laborItems[i].Lid
		var laborConversions []laborConversion
		var rate float64
		err := dao.dbBsm.Select(&laborConversions, query, lid)
		if err != nil {
			logger.Errorf("failed to get norm conversion rate: %v", err)
			return nil, err
		}
		if len(laborConversions) > 0 {
			rate = 1
			for _, r := range laborConversions {
				rate *= r.Rate
			}

			laborItems[i].Mechanic = laborItems[i].Mechanic * rate
			laborItems[i].General = laborItems[i].General * rate
		}
	}

	return laborItems, nil

}

// 获取项目机械台班金额
func (dao *designDaoImpl) GetMachineCost(pcode string, designtype int) ([]models.ProjectMachineLite, error) {
	var err error
	query := `SELECT  A.lid,COALESCE(C.mach_price*C.mach_count*A.Quantity,0)  AS machine
	  FROM
	      project_labor A 
	  LEFT JOIN 
	      project_machine B ON A.lid = B.lid 
	  LEFT JOIN 
	      norm_machine C ON B.MACH_ID=C.MACH_ID

	WHERE A.Design_Code=? AND A.Design_Type=? `
	var machineItems []models.ProjectMachineLite
	err = dao.dbBsm.Select(&machineItems, query, pcode, designtype)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, nil
		}
		logger.Errorf("获取项目机械台班金额失败 - pcode: %s, error: %v", pcode, err)
		return nil, err
	}
	if len(machineItems) == 0 {
		return nil, nil
	}

	query = "select pm.lid,nlc.rate_machine from project_labor_conversion plc left join project_machine pm  on pm.lid=plc.lid left join norm_labor_conversion nlc on plc.nci_id=nlc.id where pm.lid=?"

	type machineConversion struct {
		Lid  string  `db:"lid"`
		Rate float64 `db:"rate_machine"`
	}

	for i := 0; i < len(machineItems); i++ {
		lid := machineItems[i].Lid
		var machineConversions []machineConversion
		var rate float64
		err := dao.dbBsm.Select(&machineConversions, query, lid)
		if err != nil {
			logger.Errorf("failed to get norm conversion rate: %v", err)
			return nil, err
		}
		if len(machineConversions) > 0 {
			rate = 1
			for _, r := range machineConversions {
				rate *= r.Rate
			}

			machineItems[i].Machine = machineItems[i].Machine * rate
		}
	}

	return machineItems, nil
}

// 获取项目仪器仪表金额
func (dao *designDaoImpl) GetInstrumentCost(pcode string, designtype int) ([]models.ProjectInstrumentLite, error) {
	var err error
	query := `SELECT
	      A.lid,COALESCE(SUM(C.inst_price*C.inst_count*A.Quantity),0)  AS instrument 
	  FROM
	      project_labor A
	  LEFT JOIN
	      project_instrument B ON A.lid = B.lid
	  LEFT JOIN
	      norm_instrument C ON B.INST_ID=C.INST_ID
	WHERE A.Design_Code=? AND A.Design_Type=? `
	var instrumentItems []models.ProjectInstrumentLite
	err = dao.dbBsm.Select(&instrumentItems, query, pcode, designtype)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetInstrumentCost",
			"pcode":     pcode,
		}).Errorf("获取项目仪器仪表金额失败 - pcode: %s, error: %v", pcode, err)
		return nil, err
	}
	if len(instrumentItems) == 0 {
		return nil, nil
	}

	query = "select pi.lid,nlc.rate_instrument from project_labor_conversion plc left join project_instrument pi  on pi.lid=plc.lid left join norm_labor_conversion nlc on plc.nci_id=nlc.id where pi.lid=?"

	type instrumentConversion struct {
		Lid  string  `db:"lid"`
		Rate float64 `db:"rate_instrument"`
	}
	for i := 0; i < len(instrumentItems); i++ {
		lid := instrumentItems[i].Lid
		var instrumentConversions []instrumentConversion
		var rate float64
		err := dao.dbBsm.Select(&instrumentConversions, query, lid)
		if err != nil {
			logger.Errorf("failed to get norm conversion rate: %v", err)
			return nil, err
		}
		if len(instrumentConversions) > 0 {
			rate = 1
			for _, r := range instrumentConversions {
				rate *= r.Rate
			}

			instrumentItems[i].Instrument = instrumentItems[i].Instrument * rate
		}
	}

	return instrumentItems, nil
}

// 获取材料种类数及金额
func (dao *designDaoImpl) GetMaterialCost(designcode string, designtype int) (float64, int, error) {
	query := "SELECT COALESCE(SUM(price*quantity),0) as mcost FROM project_material WHERE design_code=? and design_type=? "

	args := []interface{}{designcode, designtype}
	var cost float64 = 0
	err := dao.dbBsm.Get(&cost, query, args...)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return 0, 0, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetMaterialCost",
			"pcode":     designcode,
		}).Errorf("获取项目材料金额失败 - pcode: %s, error: %v", designcode, err)
		return 0, 0, err
	}

	query = "select count(DISTINCT code) from project_material where design_code=? and design_type=? "
	var count int
	err = dao.dbBsm.Get(&count, query, designcode, designtype)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return 0, 0, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetMaterialCost",
			"pcode":     designcode,
		}).Errorf("获取项目材料种类数失败 - pcode: %s, error: %v", designcode, err)
		return 0, 0, err
	}

	return cost, count, nil
}

func (dao *designDaoImpl) GetDesignCodeList(orgcode string, designtype int) ([]string, error) {
	var olevel int
	query := "SELECT org_level FROM bsm_org WHERE org_code=? LIMIT 1"
	err := dao.dbBsm.Get(&olevel, query, orgcode)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetDesignCodeList",
			"orgcode":   orgcode,
		}).Errorf("获取项目组织等级失败 - orgcode: %s, error: %v", orgcode, err)
		return nil, err
	}
	var projectlist []string
	query = `SELECT design_code FROM project_base pb left join bsm_org po on pb.org_code=po.org_code where (po.org_level>? or pb.org_code=?) and project_state>=? `
	err = dao.dbBsm.Select(&projectlist, query, olevel, orgcode, designtype)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetDesignCodeList",
			"orgcode":   orgcode,
		}).Errorf("获取项目列表失败 - orgcode: %s, error: %v", orgcode, err)
		return nil, err
	}
	return projectlist, nil
}

// 获取项目立项信息
func (dao *designDaoImpl) GetProjectBase(code string) (*models.ProjectBase, error) {
	query := "SELECT id,name,design_code,approval_code,project_state,org_code,designer,initiator,reviewer,project_type,business_type,construction_type,project_overview,technical_analysis,point_old,point_new,point_cost,recycle_cycle,profit_statement FROM project_base WHERE design_code=?"
	var project models.ProjectBase
	err := dao.dbBsm.Get(&project, query, code)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetProjectBase",
			"pcode":     code,
		}).Errorf("获取项目立项信息失败 - pcode: %s, error: %v", code, err)
		return nil, err
	}
	return &project, nil
}

// 获取项目摘要信息
func (dao *designDaoImpl) GetProjectBaseLite(code string) (*models.ProjectBaseLite, error) {
	query := "SELECT id,name,design_code,org_code,designer,initiator,reviewer,project_type,business_type,project_overview,technical_analysis,preparation_date,project_state  FROM project_base WHERE design_code=?"
	var project models.ProjectBaseLite
	err := dao.dbBsm.Get(&project, query, code)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetProjectBaseLite",
			"pcode":     code,
		}).Errorf("获取项目摘要信息失败 - pcode: %s, error: %v", code, err)
		return nil, err
	}
	return &project, nil
}

// 获取项目设计配置
func (dao *designDaoImpl) GetProjectConfig(code string) (*models.ProjectDesignConfig, error) {
	query := "SELECT design_code,design_code,discount_labor,discount_machine,discount_instrument,discount_measure,discount_management,discount_profit,safe_rate,vat_rate FROM project_config WHERE design_code=?"
	var config models.ProjectDesignConfig
	err := dao.dbBsm.Get(&config, query, code)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetProjectConfig",
			"pcode":     code,
		}).Errorf("获取项目设计配置失败 - pcode: %s, error: %v", code, err)
		return nil, err
	}
	return &config, nil
}

func (dao *designDaoImpl) GetDesignID(code string) (int, error) {
	query := "SELECT id FROM project_base WHERE design_code=? "
	var id int
	args := []interface{}{code}
	err := dao.dbBsm.Get(&id, query, args...)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return -1, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetDesignID",
			"pcode":     code,
		}).Errorf("获取项目ID失败 - pcode: %s, error: %v", code, err)
		return -1, err
	}
	return id, nil
}

func (dao *designDaoImpl) GetLaborList(pcode string, designtype int) ([]models.WebProjectLaborItem, error) {
	var laborlist []models.WebProjectLaborItem

	var laborItems []models.LaborItem

	// 获取项目下的人工条目
	query := "select id,lid,design_code,design_type,code,quantity,remark from project_labor where design_code=? and design_type=? "
	args := []interface{}{pcode, designtype}
	err := dao.dbBsm.Select(&laborItems, query, args...)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetLaborList",
			"pcode":     pcode,
		}).Errorf("获取项目人工条目失败 - pcode: %s, error: %v", pcode, err)
		return nil, err
	}

	if len(laborItems) == 0 {
		return laborlist, nil
	}

	for _, item := range laborItems {

		var norm models.DesignNorm
		query := "select * from norm_labor where norm_code=? "
		args := []interface{}{item.Code}
		err := dao.dbBsm.Get(&norm, query, args...)
		if err != nil {
			if errors.Is(err, sql.ErrNoRows) {
				continue
			} else {
				logger.WithFields(map[string]interface{}{
					"layer":     "dao",
					"operation": "designDaoImpl-GetLaborList",
					"pcode":     pcode,
				}).Errorf("获取人工规格失败 - pcode: %s, error: %v", pcode, err)
				return nil, err
			}
		}

		laborlist = append(laborlist, models.WebProjectLaborItem{
			LID:      item.LID,
			NormItem: norm,
			Quantity: item.Quantity,
			Remark:   item.Remark,
		})
	}

	return laborlist, nil
}

func (dao *designDaoImpl) GetConversionList(labor_lid string) ([]models.WebProjectNormConversionItem, error) {
	query := "select plc.nci_id as id,dlnc.norm_code,dlnc.name,dlnc.content,dlnc.rate_labor,dlnc.rate_machine,dlnc.rate_instrument,dlnc.rate_material from project_labor_conversion plc left join norm_labor_conversion dlnc on plc.nci_id=dlnc.id where plc.lid = ? "
	var conversionList []models.WebProjectNormConversionItem
	args := []interface{}{labor_lid}
	err := dao.dbBsm.Select(&conversionList, query, args...)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetConversionList",
			"pcode":     labor_lid,
		}).Errorf("获取人工规格转换项列表失败 - pcode: %s, error: %v", labor_lid, err)
		return nil, err
	}
	return conversionList, nil
}

func (dao *designDaoImpl) GetMachineList(labor_lid string) ([]models.WebProjectMachineItem, error) {
	query := `
			SELECT
				pm.mach_id    AS id,
				dlm.mach_code AS code,
				dlm.mach_name AS name,
				pm.quantity  AS quantity,
				pm.remark     AS remark
			FROM project_machine pm
			LEFT JOIN norm_machine dlm
				ON pm.mach_id = dlm.mach_id
			WHERE pm.lid = ?`
	var machinelist []models.WebProjectMachineItem
	args := []interface{}{labor_lid}
	err := dao.dbBsm.Select(&machinelist, query, args...)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetMachineList",
			"pcode":     labor_lid,
		}).Errorf("获取项目机器条目列表失败 - pcode: %s, error: %v", labor_lid, err)
		return nil, err
	}
	return machinelist, nil
}

func (dao *designDaoImpl) GetInstrumentList(labor_lid string) ([]models.WebProjectInstrumentItem, error) {
	query := "select pi.inst_id as id,dli.inst_code as code,dli.inst_name as name,pi.quantity as quantity,pi.remark as remark from project_instrument pi left join norm_instrument dli on pi.inst_id=dli.inst_id where pi.lid=? "
	var instrumentlist []models.WebProjectInstrumentItem
	args := []interface{}{labor_lid}
	err := dao.dbBsm.Select(&instrumentlist, query, args...)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetInstrumentList",
			"pcode":     labor_lid,
		}).Errorf("获取项目仪表条目列表失败 - pcode: %s, error: %v", labor_lid, err)
		return nil, err
	}
	return instrumentlist, nil
}

// GetMaterialList 获取项目材料列表
func (dao *designDaoImpl) GetMaterialList(pcode string, designtype int) ([]models.WebProjectMaterialItem, error) {
	query := "SELECT pm.id,pm.design_code,pm.design_type,pm.code,dm.mat_spec as name,dm.mat_unit as unit, pm.price,pm.quantity,pm.remark FROM project_material pm left join norm_material dm on pm.code=dm.mat_code WHERE design_code=? and design_type=? "
	var materiallist []models.WebProjectMaterialItem
	args := []interface{}{pcode, designtype}
	err := dao.dbBsm.Select(&materiallist, query, args...)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetMaterialList",
			"pcode":     pcode,
		}).Errorf("获取项目材料条目列表失败 - pcode: %s, error: %v", pcode, err)
		return nil, err
	}
	return materiallist, nil
}

// GetOtherFee 获取项目其他费用列表
func (dao *designDaoImpl) GetOtherFee(pcode string, designtype int) ([]models.OtherFeeItem, error) {
	query := "select id,design_code,design_type,name,basis,tax_included,remark from project_other where design_code=? and design_type=? "
	var otherfeelist []models.OtherFeeItem
	args := []interface{}{pcode, designtype}
	err := dao.dbBsm.Select(&otherfeelist, query, args...)
	if err != nil {
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetOtherFee",
			"pcode":     pcode,
		}).Errorf("获取项目其他费用列表失败 - pcode: %s, error: %v", pcode, err)
		return nil, err
	}
	return otherfeelist, nil
}

func (dao *designDaoImpl) GetProjects(orgcode string, designtype int) ([]models.ProjectLite, error) {
	var projects []models.ProjectLite
	var args []interface{}

	query := "SELECT name, design_code, org_code, project_state, designer FROM project_base"

	conditions := []string{}

	if orgcode != "" {
		conditions = append(conditions, "org_code = ?")
		args = append(args, orgcode)
	}

	if designtype != models.DesignType_All {
		conditions = append(conditions, "project_type = ?")
		args = append(args, designtype)
	}

	if len(conditions) > 0 {
		query += " WHERE " + strings.Join(conditions, " AND ")
	}

	// query += " ORDER BY created_at DESC"

	err := dao.dbBsm.Select(&projects, query, args...)
	if err != nil {
		return nil, err
	}

	return projects, nil
}

func (dao *designDaoImpl) GetProjectState(pcode string) (int, error) {
	var state int
	query := "select project_state from project_base where design_code=? "
	args := []interface{}{pcode}
	err := dao.dbBsm.Get(&state, query, args...)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return models.ProjectState_All, nil
		}
		logger.WithFields(map[string]interface{}{
			"layer":     "dao",
			"operation": "designDaoImpl-GetProjectState",
			"pcode":     pcode,
		}).Errorf("获取项目状态失败 - pcode: %s, error: %v", pcode, err)
		return models.ProjectState_All, err
	}
	return state, nil
}
